package com.awenhui.demo.core.utils;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.UUID;

/**
 * RSA/RSA2 加密解密，签名验签
 *
 * @author yuxf
 * @version 1.0
 * @date 2020/7/7 11:21
 */
public class RSA {

    public static final String SIGN_SHA1_ALGORITHMS = "SHA1WithRSA";
    public static final String SIGN_SHA256_ALGORITHMS = "SHA256WithRSA";
    public static final String SIGN_MD5_ALGORITHMS = "MD5withRSA";
    /**
     * 生成密钥对
     *
     * @return
     * @throws Exception
     */
    public static KeyPair generateKeyPair() throws Exception {
        return generateKeyPair(1024);
    }

    /**
     * @param keysize key的长度1024/2048
     * @return
     * @throws Exception
     */
    public static KeyPair generateKeyPair(int keysize) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(keysize, new SecureRandom(UUID.randomUUID().toString().getBytes()));
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 生成签名
     *
     * @return
     */
    public static String sign( byte[] data,byte[] privateKey,String algorithm) throws Exception {
        PKCS8EncodedKeySpec pksc = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory keyfactory = KeyFactory.getInstance("RSA");
        PrivateKey pk = keyfactory.generatePrivate(pksc);
        Signature signature = Signature.getInstance(algorithm);
        signature.initSign(pk);
        signature.update(data);
        return Base64.getEncoder().encodeToString(signature.sign());
    }

    /**
     * 验证签名
     * @param data
     * @param publicKey
     * @param sign
     * @param algorithm
     * @return
     * @throws Exception
     */
    public static boolean verify(byte[] data, byte[] publicKey, String sign, String algorithm) throws Exception {
        X509EncodedKeySpec xksc = new X509EncodedKeySpec(publicKey);
        KeyFactory keyfactory = KeyFactory.getInstance("RSA");
        PublicKey pk = keyfactory.generatePublic(xksc);
        Signature signature = Signature.getInstance(algorithm);
        signature.initVerify(pk);
        signature.update(data);
        return signature.verify(Base64.getDecoder().decode(sign));
    }


    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKeyPair();
        System.out.println("公钥：" + Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
        System.out.println("私钥：" + Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()));
        byte[] data=new byte[5];
        for (int i = 0; i < 5; i++) {
            data[i]=(byte)i;
        }
        String sign=sign(data,keyPair.getPrivate().getEncoded(),SIGN_MD5_ALGORITHMS );
        System.out.println("签名："+sign);
        boolean verify = verify(data, keyPair.getPublic().getEncoded(), sign, SIGN_MD5_ALGORITHMS);
        System.out.println("验证结果："+verify);
    }

}
